package com.txf.ui_mvplibrary.ui.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;

import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
import com.txf.ui_mvplibrary.R;
import com.txf.ui_mvplibrary.interfaces.ILoadingView;
import com.txf.ui_mvplibrary.ui.view.deft.DefaultLoadingView;


/**
 * @author txf
 * @create 2019/1/29 0029
 * 继承{@link RxAppCompatActivity}
 * <p>
 * 1.提供 AlertDialog显示
 * {@link #showDialog(int, String, String, String, String, String, boolean, Bundle)}
 * 或{@link Builder}
 * AlertDialog按钮点击回调{@link #onInteractionDialogClick(DialogInterface, int, int, Bundle)}
 * <p>
 * 2.提供默认loadingView, 显示{@link #showLoading()} 隐藏 {@link #hideLoading()}}
 * 可通过重写 {@link #buildLoadingView()}改变默认loadingView
 * <p>
 * 3.提供动态切换Fragment
 * 添加:{@link #addFragment(int, Fragment, String)}
 * 隐藏:{@link #hideFragment(String)}{@link #hideFragment(Fragment)}
 * 删除:{@link #removeFragment(String)}{@link #removeFragment(Fragment)}
 */
public abstract class BaseActivity extends RxAppCompatActivity {
    private AlertDialog alertDialog;
    private ILoadingView mILoadingView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutId());
    }

    /**
     * 重写 setContentView() 添加loading层
     */
    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        mILoadingView = buildLoadingView();
        if (mILoadingView == null) {
            super.setContentView(layoutResID);
        } else {
            mILoadingView.getView().setVisibility(View.GONE);
            View view = LayoutInflater.from(this).inflate(R.layout.activity_base, null);
            FrameLayout base_activity_content = (FrameLayout) view.findViewById(R.id.base_activity_content);
            View childview = LayoutInflater.from(this).inflate(layoutResID, null);
            base_activity_content.addView(childview, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
            base_activity_content.addView(mILoadingView.getView(), mILoadingView.getViewLayoutParams());
            super.setContentView(view);
        }
    }

    protected void addFragment(@IdRes int containerViewId, Fragment fragment, @Nullable String tag) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        if (manager.findFragmentByTag(tag) == null) {
            transaction.add(containerViewId, fragment, tag);
        } else {
            transaction.show(manager.findFragmentByTag(tag));
        }
        transaction.commit();
    }

    protected void hideFragment(@Nullable String tag) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        if (manager.findFragmentByTag(tag) != null) {
            transaction.hide(manager.findFragmentByTag(tag));
            transaction.commit();
        }
    }

    protected void hideFragment(Fragment fragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        if (fragment != null) {
            transaction.hide(fragment);
            transaction.commit();
        }
    }

    protected void removeFragment(@Nullable String tag) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        if (manager.findFragmentByTag(tag) != null) {
            transaction.remove(manager.findFragmentByTag(tag));
            transaction.commit();
        }
    }

    protected void removeFragment(Fragment fragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        if (fragment != null) {
            transaction.remove(fragment);
            transaction.commit();
        }
    }

    protected ILoadingView buildLoadingView() {
        return new DefaultLoadingView(this);
    }

    protected abstract int getLayoutId();

    protected Context getContext() {
        return this;
    }

    protected void showLoading() {
        mILoadingView.show();
    }

    protected void hideLoading() {
        mILoadingView.hide();
    }

    protected int dip2px(float dipValue) {
        float scale = getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    protected void dismissDialog() {
        if (alertDialog != null) {
            alertDialog.dismiss();
            alertDialog = null;
        }
    }

    /**
     * @param with       窗口标识
     * @param title      窗口标题
     * @param content    窗口内容
     * @param button1    窗口按钮1文字
     * @param button2    窗口按钮2文字
     * @param button3    窗口按钮3文字
     * @param cancelable 窗口点击外部是否可关闭
     * @param ext        窗口额外参数
     */
    protected AlertDialog showDialog(int with, String title, String content, String button1, String button2, String button3, boolean cancelable, Bundle ext) {
        dismissDialog();
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        if (title != null)
            builder.setTitle(title);
        if (content != null)
            builder.setMessage(content);
        if (button1 != null)
            builder.setNeutralButton(button1, new DialogListener(ext, with));
        if (button2 != null)
            builder.setNegativeButton(button2, new DialogListener(ext, with));
        if (button3 != null)
            builder.setPositiveButton(button3, new DialogListener(ext, with));
        builder.setCancelable(cancelable);
        alertDialog = builder.create();
        alertDialog.show();
        return alertDialog;
    }

    /**
     * @param which DialogInterface.BUTTON_NEUTRAL
     *              DialogInterface.BUTTON_NEGATIVE
     *              DialogInterface.BUTTON_POSITIVE
     */
    protected void onInteractionDialogClick(DialogInterface dialog, int which, int with, Bundle ext) {
        dismissDialog();
    }

    private class DialogListener implements DialogInterface.OnClickListener {
        Bundle ext;
        int with;

        public DialogListener(Bundle ext, int with) {
            this.ext = ext;
            this.with = with;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            onInteractionDialogClick(dialog, which, with, ext);
        }
    }

    public class Builder {
        private int with;
        private String title;
        private String content;
        private String button1;
        private String button2;
        private String button3;
        private Bundle ext;
        private boolean cancelable = true;

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setContent(String content) {
            this.content = content;
            return this;
        }

        public Builder setButton1(String button1) {
            this.button1 = button1;
            return this;
        }

        public Builder setButton2(String button2) {
            this.button2 = button2;
            return this;
        }

        public Builder setButton3(String button3) {
            this.button3 = button3;
            return this;
        }

        public Builder setExt(Bundle ext) {
            this.ext = ext;
            return this;
        }

        public Builder setCancelable(boolean cancelable) {
            this.cancelable = cancelable;
            return this;
        }

        public Builder setWith(int with) {
            this.with = with;
            return this;
        }

        public AlertDialog show() {
            return showDialog(with, title, content, button1, button2, button3, cancelable, ext);
        }
    }
}
